

<!DOCTYPE html>
<html class="writer-html5" lang="en" >
<head>
  <meta charset="utf-8" />
  
  <meta name="viewport" content="width=device-width, initial-scale=1.0" />
  
  <title>RGW 多租户 &mdash; Ceph Documentation</title>
  

  
  <link rel="stylesheet" href="../../_static/ceph.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/pygments.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/graphviz.css" type="text/css" />
  <link rel="stylesheet" href="../../_static/css/custom.css" type="text/css" />

  
  
    <link rel="shortcut icon" href="../../_static/favicon.ico"/>
  

  
  

  

  
  <!--[if lt IE 9]>
    <script src="../../_static/js/html5shiv.min.js"></script>
  <![endif]-->
  
    
      <script type="text/javascript" id="documentation_options" data-url_root="../../" src="../../_static/documentation_options.js"></script>
        <script src="../../_static/jquery.js"></script>
        <script src="../../_static/underscore.js"></script>
        <script src="../../_static/doctools.js"></script>
    
    <script type="text/javascript" src="../../_static/js/theme.js"></script>

    
    <link rel="index" title="Index" href="../../genindex/" />
    <link rel="search" title="Search" href="../../search/" />
    <link rel="next" title="压缩" href="../compression/" />
    <link rel="prev" title="与 Open Policy Agent 对接" href="../opa/" /> 
</head>

<body class="wy-body-for-nav">

   
  <header class="top-bar">
    

















<div role="navigation" aria-label="breadcrumbs navigation">

  <ul class="wy-breadcrumbs">
    
      <li><a href="../../" class="icon icon-home"></a> &raquo;</li>
        
          <li><a href="../">Ceph 对象网关</a> &raquo;</li>
        
      <li>RGW 多租户</li>
    
    
      <li class="wy-breadcrumbs-aside">
        
          
            <a href="../../_sources/radosgw/multitenancy.rst.txt" rel="nofollow"> View page source</a>
          
        
      </li>
    
  </ul>

  
  <hr/>
</div>
  </header>
  <div class="wy-grid-for-nav">
    
    <nav data-toggle="wy-nav-shift" class="wy-nav-side">
      <div class="wy-side-scroll">
        <div class="wy-side-nav-search"  style="background: #eee" >
          

          
            <a href="../../">
          

          
            
            <img src="../../_static/logo.png" class="logo" alt="Logo"/>
          
          </a>

          

          
<div role="search">
  <form id="rtd-search-form" class="wy-form" action="../../search/" method="get">
    <input type="text" name="q" placeholder="Search docs" />
    <input type="hidden" name="check_keywords" value="yes" />
    <input type="hidden" name="area" value="default" />
  </form>
</div>

          
        </div>

        
        <div class="wy-menu wy-menu-vertical" data-spy="affix" role="navigation" aria-label="main navigation">
          
            
            
              
            
            
              <ul class="current">
<li class="toctree-l1"><a class="reference internal" href="../../start/intro/">Ceph 简介</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../install/">安装 Ceph</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cephadm/">Cephadm</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rados/">Ceph 存储集群</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../cephfs/">Ceph 文件系统</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../rbd/">Ceph 块设备</a></li>
<li class="toctree-l1 current"><a class="reference internal" href="../">Ceph 对象网关</a><ul class="current">
<li class="toctree-l2"><a class="reference internal" href="../frontends/">HTTP 前端</a></li>
<li class="toctree-l2"><a class="reference internal" href="../placement/">存储池归置与存储类</a></li>
<li class="toctree-l2"><a class="reference internal" href="../multisite/">多站配置</a></li>
<li class="toctree-l2"><a class="reference internal" href="../multisite-sync-policy/">多站同步策略配置</a></li>
<li class="toctree-l2"><a class="reference internal" href="../pools/">存储池的配置</a></li>
<li class="toctree-l2"><a class="reference internal" href="../config-ref/">配置参考</a></li>
<li class="toctree-l2"><a class="reference internal" href="../admin/">管理指南</a></li>
<li class="toctree-l2"><a class="reference internal" href="../s3/">S3 API</a></li>
<li class="toctree-l2"><a class="reference internal" href="../rgw-cache/">Data caching and CDN</a></li>
<li class="toctree-l2"><a class="reference internal" href="../swift/">Swift API</a></li>
<li class="toctree-l2"><a class="reference internal" href="../adminops/">管理操作 API</a></li>
<li class="toctree-l2"><a class="reference internal" href="../api/">Python 接口</a></li>
<li class="toctree-l2"><a class="reference internal" href="../nfs/">通过 NFS 导出</a></li>
<li class="toctree-l2"><a class="reference internal" href="../keystone/">与 OpenStack Keystone 对接</a></li>
<li class="toctree-l2"><a class="reference internal" href="../barbican/">与 OpenStack Barbican 对接</a></li>
<li class="toctree-l2"><a class="reference internal" href="../vault/">与 HashiCorp Vault 对接</a></li>
<li class="toctree-l2"><a class="reference internal" href="../kmip/">KMIP Integration</a></li>
<li class="toctree-l2"><a class="reference internal" href="../opa/">与 Open Policy Agent 对接</a></li>
<li class="toctree-l2 current"><a class="current reference internal" href="#">多租户</a><ul>
<li class="toctree-l3"><a class="reference internal" href="#id1">指定租户内的用户管理</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#id2">实例</a></li>
</ul>
</li>
<li class="toctree-l3"><a class="reference internal" href="#id3">访问指定租户的桶</a><ul>
<li class="toctree-l4"><a class="reference internal" href="#s3">S3</a></li>
<li class="toctree-l4"><a class="reference internal" href="#swift">用内置认证器的 Swift 接口</a></li>
<li class="toctree-l4"><a class="reference internal" href="#keystone-swift">用 Keystone 认证的 Swift 接口</a></li>
<li class="toctree-l4"><a class="reference internal" href="#id4">注意事项和已知问题</a></li>
</ul>
</li>
</ul>
</li>
<li class="toctree-l2"><a class="reference internal" href="../compression/">压缩</a></li>
<li class="toctree-l2"><a class="reference internal" href="../ldap-auth/">LDAP 认证</a></li>
<li class="toctree-l2"><a class="reference internal" href="../encryption/">服务器端加密</a></li>
<li class="toctree-l2"><a class="reference internal" href="../bucketpolicy/">桶策略</a></li>
<li class="toctree-l2"><a class="reference internal" href="../dynamicresharding/">动态的桶索引重分片</a></li>
<li class="toctree-l2"><a class="reference internal" href="../mfa/">多因子认证</a></li>
<li class="toctree-l2"><a class="reference internal" href="../sync-modules/">同步模块</a></li>
<li class="toctree-l2"><a class="reference internal" href="../notifications/">Bucket Notifications</a></li>
<li class="toctree-l2"><a class="reference internal" href="../layout/">RADOS 中的数据布局</a></li>
<li class="toctree-l2"><a class="reference internal" href="../STS/">STS</a></li>
<li class="toctree-l2"><a class="reference internal" href="../STSLite/">STS Lite</a></li>
<li class="toctree-l2"><a class="reference internal" href="../keycloak/">Keycloak</a></li>
<li class="toctree-l2"><a class="reference internal" href="../role/">Role</a></li>
<li class="toctree-l2"><a class="reference internal" href="../session-tags/">Session Tags</a></li>
<li class="toctree-l2"><a class="reference internal" href="../orphans/">Orphan List and Associated Tooliing</a></li>
<li class="toctree-l2"><a class="reference internal" href="../oidc/">OpenID Connect Provider</a></li>
<li class="toctree-l2"><a class="reference internal" href="../troubleshooting/">故障排除</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../man/8/radosgw/">radosgw 手册页</a></li>
<li class="toctree-l2"><a class="reference internal" href="../../man/8/radosgw-admin/">radosgw-admin 手册页</a></li>
<li class="toctree-l2"><a class="reference internal" href="../qat-accel/">使用 QAT 为加密和压缩提速</a></li>
<li class="toctree-l2"><a class="reference internal" href="../s3select/">S3-select</a></li>
<li class="toctree-l2"><a class="reference internal" href="../lua-scripting/">Lua Scripting</a></li>
<li class="toctree-l2"><a class="reference internal" href="../d3n_datacache/">D3N Data Cache</a></li>
<li class="toctree-l2"><a class="reference internal" href="../cloud-transition/">Cloud Transition</a></li>
</ul>
</li>
<li class="toctree-l1"><a class="reference internal" href="../../mgr/">Ceph 管理器守护进程</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../mgr/dashboard/">Ceph 仪表盘</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../api/">API 文档</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../architecture/">体系结构</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/developer_guide/">开发者指南</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../dev/internals/">Ceph 内幕</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../governance/">项目管理</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../foundation/">Ceph 基金会</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../ceph-volume/">ceph-volume</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../releases/general/">Ceph 版本（总目录）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../releases/">Ceph 版本（索引）</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../security/">Security</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../glossary/">Ceph 术语</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../jaegertracing/">Tracing</a></li>
<li class="toctree-l1"><a class="reference internal" href="../../translation_cn/">中文版翻译资源</a></li>
</ul>

            
          
        </div>
        
      </div>
    </nav>

    <section data-toggle="wy-nav-shift" class="wy-nav-content-wrap">

      
      <nav class="wy-nav-top" aria-label="top navigation">
        
          <i data-toggle="wy-nav-top" class="fa fa-bars"></i>
          <a href="../../">Ceph</a>
        
      </nav>


      <div class="wy-nav-content">
        
        <div class="rst-content">
        
          <div role="main" class="document" itemscope="itemscope" itemtype="http://schema.org/Article">
           <div itemprop="articleBody">
            
<div id="dev-warning" class="admonition note">
  <p class="first admonition-title">Notice</p>
  <p class="last">This document is for a development version of Ceph.</p>
</div>
  <div id="docubetter" align="right" style="padding: 5px; font-weight: bold;">
    <a href="https://pad.ceph.com/p/Report_Documentation_Bugs">Report a Documentation Bug</a>
  </div>

  
  <div class="section" id="rgw">
<span id="rgw-multitenancy"></span><h1>RGW 多租户<a class="headerlink" href="#rgw" title="Permalink to this headline">¶</a></h1>
<div class="versionadded">
<p><span class="versionmodified added">New in version Jewel.</span></p>
</div>
<p>The multi-tenancy feature allows to use buckets and users of the same
name simultaneously by segregating them under so-called <code class="docutils literal notranslate"><span class="pre">tenants</span></code>.
This may be useful, for instance, to permit users of Swift API to
create buckets with easily conflicting names such as “test” or “trove”.</p>
<p>From the Jewel release onward, each user and bucket lies under a tenant.
For compatibility, a “legacy” tenant with an empty name is provided.
Whenever a bucket is referred without an explicit tenant, an implicit
tenant is used, taken from the user performing the operation. Since
the pre-existing users are under the legacy tenant, they continue
to create and access buckets as before. The layout of objects in RADOS
is extended in a compatible way, ensuring a smooth upgrade to Jewel.</p>
<div class="section" id="id1">
<h2>指定租户内的用户管理<a class="headerlink" href="#id1" title="Permalink to this headline">¶</a></h2>
<p>这样的租户本身没有任何操作。在进行用户管理时，他们都是按需出现和消失。要想创建、修改、和删除带有租户的用户，使用
<code class="docutils literal notranslate"><span class="pre">radosgw-admin</span></code> 命令时必须额外加参数 <code class="docutils literal notranslate"><span class="pre">--tenant</span></code> 、或者用
<code class="docutils literal notranslate"><span class="pre">&lt;tenant&gt;$&lt;user&gt;</span></code> 语法指定用户。</p>
<div class="section" id="id2">
<h3>实例<a class="headerlink" href="#id2" title="Permalink to this headline">¶</a></h3>
<p>创建用户 testx$tester ，用于 S3 接口的访问：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># radosgw-admin --tenant testx --uid tester --display-name &quot;Test User&quot; --access_key TESTER --secret test123 user create</span>
</pre></div>
</div>
<p>创建用户 testx$tester ，用于 Swift 接口的访问：</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="c1"># radosgw-admin --tenant testx --uid tester --display-name &quot;Test User&quot; --subuser tester:test --key-type swift --access full user create</span>
<span class="c1"># radosgw-admin --subuser &#39;testx$tester:test&#39; --key-type swift --secret test123</span>
</pre></div>
</div>
<div class="admonition note">
<p class="admonition-title">Note</p>
<p>在 shell 里，要指定带租户的子用户时必须加引号。</p>
<p>租户名只能包含字母、数字、和下划线。</p>
</div>
</div>
</div>
<div class="section" id="id3">
<h2>访问指定租户的桶<a class="headerlink" href="#id3" title="Permalink to this headline">¶</a></h2>
<p>When a client application accesses buckets, it always operates with
credentials of a particular user. As mentioned above, every user belongs
to a tenant. Therefore, every operation has an implicit tenant in its
context, to be used if no tenant is specified explicitly. Thus a complete
compatibility is maintained with previous releases, as long as the
referred buckets and referring user belong to the same tenant.
In other words, anything unusual occurs when accessing another tenant’s
buckets <em>only</em>.</p>
<p>Extensions employed to specify an explicit tenant differ according
to the protocol and authentication system used.</p>
<div class="section" id="s3">
<h3>S3<a class="headerlink" href="#s3" title="Permalink to this headline">¶</a></h3>
<p>In case of S3, a colon character is used to separate tenant and bucket.
Thus a sample URL would be:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">https</span><span class="p">:</span><span class="o">//</span><span class="n">ep</span><span class="o">.</span><span class="n">host</span><span class="o">.</span><span class="n">dom</span><span class="o">/</span><span class="n">tenant</span><span class="p">:</span><span class="n">bucket</span>
</pre></div>
</div>
<p>Here’s a simple Python sample:</p>
<div class="highlight-python notranslate"><table class="highlighttable"><tr><td class="linenos"><div class="linenodiv"><pre><span class="normal">1</span>
<span class="normal">2</span>
<span class="normal">3</span>
<span class="normal">4</span>
<span class="normal">5</span>
<span class="normal">6</span>
<span class="normal">7</span></pre></div></td><td class="code"><div class="highlight"><pre><span></span>     <span class="kn">from</span> <span class="nn">boto.s3.connection</span> <span class="kn">import</span> <span class="n">S3Connection</span><span class="p">,</span> <span class="n">OrdinaryCallingFormat</span>
     <span class="n">c</span> <span class="o">=</span> <span class="n">S3Connection</span><span class="p">(</span>
             <span class="n">aws_access_key_id</span><span class="o">=</span><span class="s2">&quot;TESTER&quot;</span><span class="p">,</span>
             <span class="n">aws_secret_access_key</span><span class="o">=</span><span class="s2">&quot;test123&quot;</span><span class="p">,</span>
             <span class="n">host</span><span class="o">=</span><span class="s2">&quot;ep.host.dom&quot;</span><span class="p">,</span>
             <span class="n">calling_format</span> <span class="o">=</span> <span class="n">OrdinaryCallingFormat</span><span class="p">())</span>
     <span class="n">bucket</span> <span class="o">=</span> <span class="n">c</span><span class="o">.</span><span class="n">get_bucket</span><span class="p">(</span><span class="s2">&quot;test5b:testbucket&quot;</span><span class="p">)</span>
</pre></div>
</td></tr></table></div>
<p>Note that it’s not possible to supply an explicit tenant using
a hostname. Hostnames cannot contain colons, or any other separators
that are not already valid in bucket names. Using a period creates an
ambiguous syntax. Therefore, the bucket-in-URL-path format has to be
used.</p>
<p>Due to the fact that the native S3 API does not deal with
multi-tenancy and radosgw’s implementation does, things get a bit
involved when dealing with signed URLs and public read ACLs.</p>
<ul>
<li><p>A <strong>signed URL</strong> does contain the <code class="docutils literal notranslate"><span class="pre">AWSAccessKeyId</span></code> query
parameters, from which radosgw is able to discern the correct user
and tenant owning the bucket. In other words, an application
generating signed URLs should be able to take just the un-prefixed
bucket name, and produce a signed URL that itself contains the
bucket name without the tenant prefix. However, it is <em>possible</em> to
include the prefix if you so choose.</p>
<p>Thus, accessing a signed URL of an object <code class="docutils literal notranslate"><span class="pre">bar</span></code> in a container
<code class="docutils literal notranslate"><span class="pre">foo</span></code> belonging to the tenant <code class="docutils literal notranslate"><span class="pre">7188e165c0ae4424ac68ae2e89a05c50</span></code>
would be possible either via
<code class="docutils literal notranslate"><span class="pre">http://&lt;host&gt;:&lt;port&gt;/foo/bar?AWSAccessKeyId=b200fb6634c547199e436a0f93c0c46e&amp;Expires=1542890806&amp;Signature=eok6CYQC%2FDwmQQmqvY5jTg6ehXU%3D</span></code>,
or via
<code class="docutils literal notranslate"><span class="pre">http://&lt;host&gt;:&lt;port&gt;/7188e165c0ae4424ac68ae2e89a05c50:foo/bar?AWSAccessKeyId=b200fb6634c547199e436a0f93c0c46e&amp;Expires=1542890806&amp;Signature=eok6CYQC%2FDwmQQmqvY5jTg6ehXU%3D</span></code>,
depending on whether or not the tenant prefix was passed in on
signature generation.</p>
</li>
<li><p>A bucket with a <strong>public read ACL</strong> is meant to be read by an HTTP
client <em>without</em> including any query parameters that would allow
radosgw to discern tenants. Thus, publicly readable objects must
always be accessed using the bucket name with the tenant prefix.</p>
<p>Thus, if you set a public read ACL on an object <code class="docutils literal notranslate"><span class="pre">bar</span></code> in a
container <code class="docutils literal notranslate"><span class="pre">foo</span></code> belonging to the tenant
<code class="docutils literal notranslate"><span class="pre">7188e165c0ae4424ac68ae2e89a05c50</span></code>, you would need to access that
object via the public URL
<code class="docutils literal notranslate"><span class="pre">http://&lt;host&gt;:&lt;port&gt;/7188e165c0ae4424ac68ae2e89a05c50:foo/bar</span></code>.</p>
</li>
</ul>
</div>
<div class="section" id="swift">
<h3>用内置认证器的 Swift 接口<a class="headerlink" href="#swift" title="Permalink to this headline">¶</a></h3>
<p>TBD – not in test_multen.py yet</p>
</div>
<div class="section" id="keystone-swift">
<h3>用 Keystone 认证的 Swift 接口<a class="headerlink" href="#keystone-swift" title="Permalink to this headline">¶</a></h3>
<p>In the default configuration, although native Swift has inherent
multi-tenancy, radosgw does not enable multi-tenancy for the Swift
API. This is to ensure that a setup with legacy buckets — that is,
buckets that were created before radosgw supported multitenancy —,
those buckets retain their dual-API capability to be queried and
modified using either S3 or Swift.</p>
<p>If you want to enable multitenancy for Swift, particularly if your
users only ever authenticate against OpenStack Keystone, you should
enable Keystone-based multitenancy with the following <code class="docutils literal notranslate"><span class="pre">ceph.conf</span></code>
configuration option:</p>
<div class="highlight-default notranslate"><div class="highlight"><pre><span></span><span class="n">rgw</span> <span class="n">keystone</span> <span class="n">implicit</span> <span class="n">tenants</span> <span class="o">=</span> <span class="n">true</span>
</pre></div>
</div>
<p>Once you enable this option, any newly connecting user (whether they
are using the Swift API, or Keystone-authenticated S3) will prompt
radosgw to create a user named <code class="docutils literal notranslate"><span class="pre">&lt;tenant_id&gt;$&lt;tenant_id</span></code>, where
<code class="docutils literal notranslate"><span class="pre">&lt;tenant_id&gt;</span></code> is a Keystone tenant (project) UUID — for example,
<code class="docutils literal notranslate"><span class="pre">7188e165c0ae4424ac68ae2e89a05c50$7188e165c0ae4424ac68ae2e89a05c50</span></code>.</p>
<p>Whenever that user then creates an Swift container, radosgw internally
translates the given container name into
<code class="docutils literal notranslate"><span class="pre">&lt;tenant_id&gt;/&lt;container_name&gt;</span></code>, such as
<code class="docutils literal notranslate"><span class="pre">7188e165c0ae4424ac68ae2e89a05c50/foo</span></code>. This ensures that if there
are two or more different tenants all creating a container named
<code class="docutils literal notranslate"><span class="pre">foo</span></code>, radosgw is able to transparently discern them by their tenant
prefix.</p>
<p>It is also possible to limit the effects of implicit tenants
to only apply to swift or s3, by setting <code class="docutils literal notranslate"><span class="pre">rgw</span> <span class="pre">keystone</span> <span class="pre">implicit</span> <span class="pre">tenants</span></code>
to either <code class="docutils literal notranslate"><span class="pre">s3</span></code> or <code class="docutils literal notranslate"><span class="pre">swift</span></code>.  This will likely primarily
be of use to users who had previously used implicit tenants
with older versions of ceph, where implicit tenants
only applied to the swift protocol.</p>
</div>
<div class="section" id="id4">
<h3>注意事项和已知问题<a class="headerlink" href="#id4" title="Permalink to this headline">¶</a></h3>
<p>Just to be clear, it is not possible to create buckets in other
tenants at present. The owner of newly created bucket is extracted
from authentication information.</p>
</div>
</div>
</div>



           </div>
           
          </div>
          <footer>
    <div class="rst-footer-buttons" role="navigation" aria-label="footer navigation">
        <a href="../compression/" class="btn btn-neutral float-right" title="压缩" accesskey="n" rel="next">Next <span class="fa fa-arrow-circle-right" aria-hidden="true"></span></a>
        <a href="../opa/" class="btn btn-neutral float-left" title="与 Open Policy Agent 对接" accesskey="p" rel="prev"><span class="fa fa-arrow-circle-left" aria-hidden="true"></span> Previous</a>
    </div>

  <hr/>

  <div role="contentinfo">
    <p>
        &#169; Copyright 2016, Ceph authors and contributors. Licensed under Creative Commons Attribution Share Alike 3.0 (CC-BY-SA-3.0).

    </p>
  </div> 

</footer>
        </div>
      </div>

    </section>

  </div>
  

  <script type="text/javascript">
      jQuery(function () {
          SphinxRtdTheme.Navigation.enable(true);
      });
  </script>

  
  
    
   

</body>
</html>